package com.kamistoat.ruoyi.ruoyimodulessystem.service.impl;

import com.kamistoat.ruoyi.ruoyiapisystem.domain.SysDictType;
import com.kamistoat.ruoyi.ruoyiapisystem.entity.SysDictDataEntity;
import com.kamistoat.ruoyi.ruoyicommoncore.exception.ServiceException;
import com.kamistoat.ruoyi.ruoyicommoncore.utils.StringUtils;
import com.kamistoat.ruoyi.ruoyicommoncore.utils.page.Query;
import com.kamistoat.ruoyi.ruoyicommonsecurity.utils.DictUtils;
import com.kamistoat.ruoyi.ruoyimodulessystem.service.SysDictDataService;
import com.kamistoat.ruoyi.ruoyimodulessystem.service.SysDictTypeService;
import com.kamistoat.ruoyi.ruoyimodulessystem.dao.SysDictTypeDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kamistoat.ruoyi.ruoyicommoncore.utils.page.PageUtils;
import com.kamistoat.ruoyi.ruoyiapisystem.entity.SysDictTypeEntity;


@Service("sysDictTypeService")
public class SysDictTypeServiceImpl extends ServiceImpl<SysDictTypeDao, SysDictTypeEntity> implements SysDictTypeService {

    @Autowired
    SysDictDataService sysDictDataService;
    @Autowired
    DictUtils dictUtils;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<SysDictTypeEntity> page = this.page(
                new Query<SysDictTypeEntity>().getPage(params),
                new QueryWrapper<SysDictTypeEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public List<SysDictTypeEntity> selectDictTypeList(SysDictType sysDictType) {
        QueryWrapper<SysDictTypeEntity> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotEmpty(sysDictType.getDictName())) {
            queryWrapper.eq("dict_name", sysDictType.getDictName());
        }
        if (StringUtils.isNotEmpty(sysDictType.getDictType())) {
            queryWrapper.eq("dict_type", sysDictType.getDictType());
        }
        if (StringUtils.isNotEmpty(sysDictType.getStatus())) {
            queryWrapper.eq("status", sysDictType.getStatus());
        }
        if (StringUtils.isNotEmpty((String) sysDictType.getParams().get("beginTime"))) {
            queryWrapper.ge("create_time", sysDictType.getParams().get("beginTime"));
        }
        if (StringUtils.isNotEmpty((String) sysDictType.getParams().get("endTime"))) {
            queryWrapper.le("create_time", sysDictType.getParams().get("endTime"));
        }
        return this.list(queryWrapper);
    }

    /**
     * 判断字典类型是否已经存在
     */
    @Override
    public boolean checkDictTypeUnique(SysDictType sysDictType) {
        SysDictTypeEntity one = this.getOne(new QueryWrapper<SysDictTypeEntity>()
                .select("dict_id")
                .eq("dict_type", sysDictType.getDictType()));
        return StringUtils.isNotNull(one) && !one.getDictId().equals(sysDictType.getDictId());
    }

    /**
     * 修改字典类型并更新缓存
     *
     * @param sysDictTypeEntity
     */
    @Override
    public boolean updateDictTypeAndCache(SysDictTypeEntity sysDictTypeEntity) {
        // 修改前的type
        SysDictTypeEntity oldType =
                this.getOne(new QueryWrapper<SysDictTypeEntity>()
                        .eq("dict_id", sysDictTypeEntity.getDictId()));

        // 如果 dict_type字段修改了，则需要联动修改并删除缓存
        if (!StringUtils.equals(oldType.getDictType(), sysDictTypeEntity.getDictType())) {
            List<SysDictDataEntity> oldDataList =
                    sysDictDataService.list(new QueryWrapper<SysDictDataEntity>()
                            .eq("dict_type", sysDictTypeEntity.getDictType()));
            for (SysDictDataEntity oldData : oldDataList) {
                oldData.setDictType(sysDictTypeEntity.getDictType());
            }
            sysDictDataService.updateBatchById(oldDataList);
            dictUtils.removeDictCache(oldType.getDictType());
        }

        return this.updateById(sysDictTypeEntity);
    }

    /**
     * 删除并删除缓存
     *
     * @param dictIds
     */
    @Override
    public boolean deleteDictTypeByIdsAndRemoveCache(Long[] dictIds) {
        boolean res = true;
        for (Long dictId : dictIds) {
            String deletedDictType = this.getOne(new QueryWrapper<SysDictTypeEntity>()
                    .select("dict_type")
                    .eq("dict_id", dictId)).getDictType();
            Integer count = sysDictDataService.getBaseMapper().selectCount(new QueryWrapper<SysDictDataEntity>()
                    .select("dict_label")
                    .eq("dict_type", deletedDictType)
                    .last("LIMIT 1"));
            if (count > 0) {
                throw new ServiceException("无法删除'" + deletedDictType + "', 类型含有未删除的字典数据");
            }
            res = res && this.removeById(dictId);
            dictUtils.removeDictCache(deletedDictType);
        }
        return res;
    }

    /**
     * 重置缓存
     */
    @Override
    public void resetDictCache() {
        dictUtils.clearDictCache();
        List<SysDictTypeEntity> sysDictTypeEntityList = this.selectDictTypeList(new SysDictType());
        for (SysDictTypeEntity sysDictTypeEntity : sysDictTypeEntityList) {
            sysDictDataService.selectDictDataByTypeAndCache(sysDictTypeEntity.getDictType());
        }
    }

}